/*+**************************************************************************/
/***                                                                      ***/
/***   This file is distributed under a BSD license.                      ***/
/***   See LICENSE.txt for details.                                       ***/
/***                                                                      ***/
/**************************************************************************+*/

/****************************************************************************/
/***                                                                      ***/
/***   (C) 2005 Dierk Ohlerich, all rights reserved                       ***/
/***                                                                      ***/
/****************************************************************************/

level11;

asc
{
  cbuffer TestMtrlHSPara : register(c0) : slot hs 0
  {
    float4 tess;
  };
  cbuffer TestMtrlGSPara : register(c0) : slot gs 0
  {
    row_major float4x4 mvp;
    float4 ldir;
  };
}

material TestMtrl 
{
  asc 
  {
    struct ia_t
    {
      float3 pos : POSITION;            // input, from vertex array
      float3 norm : NORMAL;
      float2 uv : TEXCOORD0;
    };
    struct vs_t
    {
      float3 pos : POS;
      float3 norm : NORMAL;
    };
    struct hs_t
    {
      float3 pos : POS;
      float3 norm : NORMAL;
    };
    struct hc_t
    {
      float Edges[3] : SV_TessFactor;
      float Inside : SV_InsideTessFactor;
    };
    struct ds_t
    {
      float3 pos : POS;
      float3 norm : NORMAL;
    };
    struct gs_t
    {
      float4 col : COLOR0;
      float4 pos : SV_Position;
    };
  }

  vs asc vs_5_0                 // hlsl code
  {
    sampler2D s0 : register(s0);

    void main
    ( 
      in ia_t i,
      out vs_t o
    ) 
    {
      o.pos = i.pos;
      o.norm = i.norm;
    }
  }


  hs asc hs_5_0
  {
    use TestMtrlHSPara;
    hc_t mainc
    (
      in InputPatch<vs_t,3> i,
    )
    { 
      hc_t o;
      o.Edges[0] = o.Edges[1] = o.Edges[2] = tess.x;
      o.Inside = tess.x;

      return o;
    }
    [domain("tri")]
    [partitioning("fractional_odd")]
    [outputtopology("triangle_cw")]
    [outputcontrolpoints(3)]
    [patchconstantfunc("mainc")]
    [maxtessfactor(9.0)]
    hs_t main
    (
      in InputPatch<vs_t,3> i,
      uint id : SV_OutputControlPointID,
    )
    {
      hs_t o;
      o.pos = i[id].pos;
      o.norm = i[id].norm;
      return o;
    }
  }

  ds asc ds_5_0
  {
    [domain("tri")]
    void main
    (
      in hc_t c,
      in OutputPatch<hs_t,3> i,
      in float3 bc : SV_DomainLocation,
      out ds_t o,
    )
    {
      float3 pos;
      o.norm = i[0].norm*bc.x + i[1].norm*bc.y + i[2].norm*bc.z;
      o.pos  = i[0].pos *bc.x + i[1].pos *bc.y + i[2].pos *bc.z;
    }
  }

  gs asc gs_5_0
  {
    use TestMtrlGSPara;
    [maxvertexcount(3)]
    void main
    (
      triangle ds_t i[3],
      inout TriangleStream<gs_t> stream,
    )
    {
      gs_t o;

      float3 norm = normalize(i[0].norm+i[1].norm+i[2].norm);

      float l = saturate(dot(norm,ldir))*0.75+0.15;

      o.col = float4(l,l,l,1);

      o.pos = mul(float4(i[0].pos,1),mvp);
      stream.Append(o);
      o.pos = mul(float4(i[1].pos,1),mvp);
      stream.Append(o);
      o.pos = mul(float4(i[2].pos,1),mvp);
      stream.Append(o);
    }
  }

  ps asc ps_5_0
  {
    void main
    (
      in float4 col : COLOR0,
      out float4 result : COLOR0
    )
    {
      result = col;
    }
  }
};

  